package com.xhy.documents_collection.controller.caption;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.xhy.documents_collection.annotations.FileLog;
import com.xhy.documents_collection.annotations.OperLog;
import com.xhy.documents_collection.enums.BusinessType;
import com.xhy.documents_collection.enums.ServiceType;
import com.xhy.documents_collection.holder.UserHolder;
import com.xhy.documents_collection.annotations.Authority;
import com.xhy.documents_collection.cache.UserCache;
import com.xhy.documents_collection.entity.PO.User;
import com.xhy.documents_collection.entity.PO.task.Task;
import com.xhy.documents_collection.entity.PO.task.TaskRecord;
import com.xhy.documents_collection.entity.PO.task.TroopUser;
import com.xhy.documents_collection.entity.PO.team.Team;
import com.xhy.documents_collection.annotations.Restriction;
import com.xhy.documents_collection.service.*;
import com.xhy.documents_collection.service.oss.OssService;
import com.xhy.documents_collection.service.task.TaskRecordService;
import com.xhy.documents_collection.service.task.TaskService;
import com.xhy.documents_collection.service.task.TroopUserService;
import com.xhy.documents_collection.service.team.TeamService;
import com.xhy.documents_collection.utils.R;
import com.xhy.documents_collection.utils.TransitionByteToCH;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.util.ObjectUtils;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletResponse;
import java.util.*;
import java.util.stream.Collectors;

/**
 * Author: Xhy
 * CreateTime: 2022-11-19 14:38
 * 团队负责人的文件管理
 */

@RestController
@RequestMapping("/caption/task")
public class CTaskController {

    @Resource
    private TaskService taskService;

    @Resource
    private TaskRecordService taskRecordService;

    @Resource
    private TeamService teamService;

    /**
     * 团队负责人所管理的任务列表
     * @param current
     * @param limit
     * @param name
     * @return
     */
    @GetMapping("/page")
    @Authority("caption:task:page")
    public R page(@RequestParam(value = "page") Long current,
                  @RequestParam(value = "limit") Long limit,
                  @RequestParam(required = false) String name
    ){
        Integer uId = UserHolder.get();
        Page<Task> page = taskService.page(new Page<>(current, limit),
                new LambdaQueryWrapper<Task>().eq(Task::getUId, uId).like(!ObjectUtils.isEmpty(name), Task::getName, name).orderByDesc(Task::getGmtCreated));

        Map<Integer,  String> teamMap = teamService.list(new QueryWrapper<Team>().select("id", "name"))
                .stream()
                .collect(Collectors.toMap(Team::getId, Team::getName));
        // 填充信息: 1.完成人数 2.任务状态
        for (Task task : page.getRecords()) {
            // 获取全部人数
            int allCount = taskRecordService.count(new QueryWrapper<TaskRecord>().eq("t_id", task.getId()));
            // 获取已完成人数
            int finishCount = taskRecordService.count(new QueryWrapper<TaskRecord>().eq("t_id", task.getId()).eq("is_submit", 1));
            task.setFinishState(finishCount+"/"+allCount);
            // 填充任务状态
            task.setTimeState(new Date().compareTo(task.getEndTime()) == 1  ? false : true);
            // 填充任务所属团队
            task.setTeamName(teamMap.get(task.getTId()));
            task.setUrl("");
            task.setFilePath(new String(Base64.getEncoder().encode(task.getFilePath().getBytes())));
        }
        return R.ok().data("data",page.getRecords()).count(page.getTotal());
    }


    // 获取用户的任务(不包含已经定时的任务)
    @GetMapping("/listNoIncludeTiming")
    @Authority("caption:task:listNoIncludeTiming")
    public R listNoIncludeTiming(){
        Integer userId = UserHolder.get();
        // 0.查出正在进行中的任务
        List<Task> tasks = taskService.list(new LambdaQueryWrapper<Task>().eq(Task::getUId, userId));
        // 当前时间小于task中endTime
        Set<Integer> taskIds = tasks.stream().filter(task -> new Date().toInstant().isBefore(task.getEndTime().toInstant()))
                .map(Task::getId)
                .collect(Collectors.toSet());
        // 1.再查
        if (ObjectUtils.isEmpty(taskIds)){
            return R.ok().data("data",Collections.EMPTY_LIST);
        }
        List<Task> task = taskService.list(new LambdaQueryWrapper<Task>()
                .in(!ObjectUtils.isEmpty(taskIds), Task::getId, taskIds).eq(Task::getUId,userId).select(Task::getId,Task::getName));
        return R.ok().data("data",task);
    }


    // 发布任务 因为要携带文件因此前端发送的是表单请求
    @PostMapping
    @Authority("caption:task:add")
    @OperLog(title = ServiceType.TASK,businessType = BusinessType.INSERT)
    public R add( Task task){
        return taskService.issueTask(task);
    }

    // 修改任务 因为要携带文件因此前端发送的是表单请求
    @PutMapping
    @Authority("caption:task:update")
    @OperLog(title = ServiceType.TASK,businessType = BusinessType.UPDATE)
    public R update(Task task){
        return taskService.update(task);
    }

    // 删除任务
    @DeleteMapping("/{ids}")
    @Authority("caption:task:delete")
    @OperLog(title = ServiceType.TASK,businessType = BusinessType.DELETE)
    public R delete(@PathVariable String ids){

        return taskService.deleteTasks(Arrays.asList(ids.split(",")).stream().map(Integer::parseInt).collect(Collectors.toList()));
    }

    @Resource
    private TroopUserService troopUserService;

    private void setUserName(TaskRecord taskRecord){
        if(taskRecord.getTroopId()!=-1){
            StringJoiner joiner = new StringJoiner("-");
            List<Integer> userIds = troopUserService.list(new QueryWrapper<TroopUser>().eq("troop_id", taskRecord.getTroopId()).select("u_id")).stream().map(TroopUser::getUId).collect(Collectors.toList());
            for (Integer userId : userIds) {
                joiner.add(UserCache.get(userId));
            }
            taskRecord.setUserName(joiner.toString());
        }else {
            taskRecord.setUserName(UserCache.get(taskRecord.getUId()));
        }
    }

    @Resource
    private UserService userService;

    // 获取任务下的所有记录
    @GetMapping("/record/page/{taskId}")
    @Authority("caption:task:page")
    public R recordPage(@RequestParam(value = "page") Long current,
                  @RequestParam(value = "limit") Long limit,
                  @RequestParam(required = false) Integer isSubmit,
                  @PathVariable String taskId
    ){

        Page<TaskRecord> page = taskRecordService.page(new Page<>(current, limit),
        new QueryWrapper<TaskRecord>().eq(!ObjectUtils.isEmpty(isSubmit),"is_submit",isSubmit)
                .eq("t_id",taskId));
        // 填充用户信息
        HashMap<Integer, String> userMap = new HashMap<>();
        userService.list(new QueryWrapper<User>().select("id","name"))
                .stream()
                .forEach(user -> {
                    userMap.put(user.getId(),user.getName());
                });
        for (TaskRecord taskRecord : page.getRecords()) {
            setUserName(taskRecord);
            // 填充文件大小
            taskRecord.setFileSizeString(TransitionByteToCH.getPrintSize(taskRecord.getFileSize()));
            taskRecord.setUrl("");

            taskRecord.setFilePath(new String(Base64.getEncoder().encode(taskRecord.getFilePath().getBytes())));
        }
        // 过滤数据
        Set<Integer> filterMap = new HashSet<>();
        Iterator<TaskRecord> it = page.getRecords().iterator();
        while (it.hasNext()){
            TaskRecord taskRecord = it.next();
            if (taskRecord.getTroopId() != -1){
                // 查看缓存中是否有组队过
                if (filterMap.contains(taskRecord.getTroopId())){
                    it.remove();
                }else {
                    filterMap.add(taskRecord.getTroopId());
                }
            }
        }
        return R.ok().data("data",page.getRecords()).count(page.getTotal());
    }
    @Resource
    private OssService ossService;


    /**
     * 上传文件
     * @param file 文件
     * @param taskRecordId 上传任务记录id
     * @return
     */
    @PostMapping("/upload")
    @Authority("caption:task:upload")
    @Restriction(limit = 8,time = 3600)
    @FileLog(title = ServiceType.OSS,businessType = BusinessType.UPLOAD)
    public R upload(MultipartFile file
            ,String taskRecordId){
        return ossService.captionUpload(file,taskRecordId);
    }

    // 退回文件
    @DeleteMapping("/sendBack/{taskRecordId}")
    @Authority("caption:task:sendBack")
    @FileLog(title = ServiceType.OSS,businessType = BusinessType.SEND_BACK)
    @Restriction(limit = 8,time = 3600)
    public R sendBack(@PathVariable  String taskRecordId){
        return ossService.captionSendBack(taskRecordId);
    }


    // 下载文件
    @PostMapping("/download/{taskRecordIds}")
    @Authority("caption:task:download")
    @Restriction(limit = 8,time = 3600)
    @FileLog(title = ServiceType.OSS,businessType = BusinessType.DOWNLOAD)
    public R download(@PathVariable String taskRecordIds, HttpServletResponse response){

        return ossService.download(taskRecordIds,response);
    }
}
